﻿using MR.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace MeetFuture.MRC
{
    public static class ApplicationGlobal
    {
        public static string ConnectString_ERack = string.Empty;
        public static string ConnectString_MRC = string.Empty;
        public static string RV_Daemon = string.Empty;
        public static string Crlf = "\r\n";
        public static string Cr = "\r";
        public static string Lf = "\n";
        public static char[] configSplitChar = ",".ToCharArray();
        public static string key_this = "RV";
        public static string key_rv_eap = "RV_EAP";
        public static string key_rv_ers = "RV_ERS";
        public static string key_mrcsrv = "MRC_SRV";
        public static string key_eapsrv = "EAP_SRV";
        public static string key_mrdsrv = "MRD_SRV";
        public static string key_fmbsrv = "EQPFABMONITOR";
        public static string key_querysrv = "QUERY_SRV";
        public static string key_erackdb = "ERACK_DB";
        public static string key_mrcdb = "MRC_DB";
        public static string key_rvmsg = "RVMessage";
        public static string key_holddepartment = "HoldDepartment";
        public static int RV_Timeout = 30;
        public static string key_AGV_Mapping = "AGV_Mapping";
        public static string key_AGVID = "AGVID";
        public static string key_AGV_Event_Message = "AGVEVENTMESSAGE";
        public static string key_EmptyPod_Mapping = "EmptyPod_Mapping";
        public static string key_LotID_Error = "Can_Not_Read_Tag";
        public static long transId = 1;
        public static long transId_RV = 1;

        public const string KEY_EAPSTATUSRETYING_AWAITTIME = "EAPStatusRetryingAwaitTime";

        public static string GetValueByKey(string Msg, string key)
        {
            string result = string.Empty;
            try
            {
                Msg += " ";
                int startIndex = Msg.ToUpper().IndexOf(key.ToUpper());
                if (startIndex >= 0)
                {
                    startIndex = startIndex + key.Length + 1;
                    int endIndex = Msg.ToUpper().IndexOf(" ", startIndex);
                    result = Msg.Substring(startIndex, endIndex - startIndex);
                }
            }
            catch (System.Exception ex)
            {
            }
            return result;
        }

        public static string GetValueByKey(string msg, string key, string split)
        {
            string result = string.Empty;
            try
            {
                msg += " ";
                int length = key.Length + 1;
                result = msg.Substring(msg.IndexOf(key) + length, msg.IndexOf(split, msg.IndexOf(key) + length) - msg.IndexOf(key) - length);
            }
            catch (System.Exception ex)
            {
            }
            return result;
        }

        public static string GetItem(string Item)
        {
            string result = string.Empty;
            try
            {
                string pattern = @"(?i)(?<=\[)(.*)(?=\])";
                Regex rgx = new Regex(pattern);
                result = rgx.Match(Item).Value;
            }
            catch (System.Exception ex)
            {
            }
            return result;
        }

        public static List<string> GetSubItem(string Item)
        {
            List<string> result = new List<string>();
            try
            {
                string pattern = @"\[[^\[^\]]*\]";
                Regex rgx = new Regex(pattern);
                MatchCollection matches = rgx.Matches(Item);
                foreach (Match group in matches)
                {
                    result.Add(group.ToString());
                }
            }
            catch (System.Exception ex)
            {
            }
            return result;
        }

        public static string GetTransID()
        {
            string result = string.Empty;
            try
            {
                if (transId >= 99999999)
                {
                    transId = 1;
                }
                result = transId.ToString().PadLeft(8, '0');
                transId++;
            }
            catch (System.Exception ex)
            {
                transId = 1;
                result = transId.ToString().PadLeft(8, '0');
                transId++;
            }
            return result;
        }

        public static string GetRVTransID()
        {
            string result = string.Empty;
            try
            {
                result = transId_RV.ToString();
                transId_RV++;
            }
            catch (System.Exception ex)
            {
                transId_RV = 1;
                result = transId_RV.ToString();
                transId_RV++;
            }
            return result;
        }

        //public static string ReturnLotStatus(LotStatus lotStatus)
        //{
        //    string result = "UNKOWN";
        //    try
        //    {
        //        switch (lotStatus)
        //        {
        //            case LotStatus.Lot_JobPrepared:
        //            {
        //                result = "PREPARE";
        //                break;
        //            }
        //            case LotStatus.Lot_OnRack:
        //            {
        //                result = "INRACK";
        //                break;
        //            }
        //            case LotStatus.Lot_PDSend:
        //            {
        //                result = "PDSEND";
        //                break;
        //            }
        //            case LotStatus.Lot_OnAGV:
        //            {
        //                result = "INRBT";
        //                break;
        //            }
        //            case LotStatus.Lot_OnTool:
        //            {
        //                result = "INEQP";
        //                break;
        //            }
        //            case LotStatus.Lot_JOR:
        //            {
        //                result = "JO";
        //                break;
        //            }
        //            case LotStatus.Lot_Error:
        //            {
        //                result = "ERROR";
        //                break;
        //            }
        //            default:
        //            {
        //                break;
        //            }
        //        }
        //    }
        //    catch (System.Exception ex)
        //    {
        //    }
        //    return result;
        //}

        public static string GetToolStatusCode(string Status)
        {
            string result = string.Empty;
            try
            {
                switch (Status.ToUpper())
                {
                    case "R":
                    case "RUN":
                    {
                        result = "1";
                        break;
                    }
                    case "I":
                    case "LOST":
                    {
                        result = "2";
                        break;
                    }
                    case "D":
                    case "DOWN":
                    {
                        result = "3";
                        break;
                    }
                    case "L":
                    case "TEST":
                    {
                        result = "4";
                        break;
                    }
                    case "CIMD":
                    {
                        result = "5";
                        break;
                    }
                    case "PM":
                    {
                        result = "6";
                        break;
                    }
                    case "W_MF":
                    {
                        result = "7";
                        break;
                    }
                    case "P":
                    case "MON":
                    {
                        result = "8";
                        break;
                    }
                    case "W_EN":
                    {
                        result = "9";
                        break;
                    }
                    case "FACD":
                    {
                        result = "10";
                        break;
                    }
                    case "M_DW":
                    {
                        result = "11";
                        break;
                    }
                    case "PM_M":
                    {
                        result = "12";
                        break;
                    }
                    case "H":
                    case "OFF":
                    {
                        result = "13";
                        break;
                    }
                    case "T_MD":
                    {
                        result = "14";
                        break;
                    }
                    case "BKUP":
                    {
                        result = "15";
                        break;
                    }
                    case "DTST":
                    {
                        result = "16";
                        break;
                    }
                    case "DUMY":
                    {
                        result = "17";
                        break;
                    }
                    case "PCON":
                    {
                        result = "18";
                        break;
                    }
                    case "W_PT":
                    {
                        result = "19";
                        break;
                    }
                    case "FACP":
                    {
                        result = "20";
                        break;
                    }
                    case "PMPE":
                    {
                        result = "21";
                        break;
                    }
                    default:
                    {
                        break;
                    }
                }
            }
            catch (System.Exception ex)
            {
            }
            return result;
        }

        public static string GetToolStatusByCode(string StatusCode)
        {
            string result = string.Empty;
            try
            {
                switch (StatusCode.ToUpper())
                {
                    case "1":
                    {
                        result = "RUN";
                        break;
                    }
                    case "2":
                    {
                        result = "LOST";
                        break;
                    }
                    case "3":
                    {
                        result = "DOWN";
                        break;
                    }
                    case "4":
                    {
                        result = "TEST";
                        break;
                    }
                    case "5":
                    {
                        result = "CIMD";
                        break;
                    }
                    case "6":
                    {
                        result = "PM";
                        break;
                    }
                    case "7":
                    {
                        result = "W_MF";
                        break;
                    }
                    case "8":
                    {
                        result = "MON";
                        break;
                    }
                    case "9":
                    {
                        result = "W_EN";
                        break;
                    }
                    case "10":
                    {
                        result = "FACD";
                        break;
                    }
                    case "11":
                    {
                        result = "M_DW";
                        break;
                    }
                    case "12":
                    {
                        result = "PM_M";
                        break;
                    }
                    case "13":
                    {
                        result = "OFF";
                        break;
                    }
                    case "14":
                    {
                        result = "T_MD";
                        break;
                    }
                    case "15":
                    {
                        result = "BKUP";
                        break;
                    }
                    case "16":
                    {
                        result = "DTST";
                        break;
                    }
                    case "17":
                    {
                        result = "DUMY";
                        break;
                    }
                    case "18":
                    {
                        result = "PCON";
                        break;
                    }
                    case "19":
                    {
                        result = "W_PT";
                        break;
                    }
                    case "20":
                    {
                        result = "FACP";
                        break;
                    }
                    case "21":
                    {
                        result = "PMPE";
                        break;
                    }
                    default:
                    {
                        break;
                    }
                }
            }
            catch (System.Exception ex)
            {
            }
            return result;
        }

        public static string GetPortStatusCode(string Status)
        {
            string result = string.Empty;
            try
            {
                switch (Status.ToUpper())
                {
                    case "E":   //IDLE
                    case "U":   //IDLE
                    case "UP":
                    {
                        result = "1";
                        break;
                    }
                    case "R":   //RUN
                    case "RUN":
                    {
                        result = "2";
                        break;
                    }
                    case "D":   //DOWN
                    case "DOWN":
                    {
                        result = "3";
                        break;
                    }
                    case "W":    //WAITENG
                    case "W_EN":
                    {
                        result = "4";
                        break;
                    }
                    default:
                    {
                        break;
                    }
                }
            }
            catch (System.Exception ex)
            {
            }
            return result;
        }

        public static clsBatchInfo ParseBatchInfo(clsRVMsg rvMsg)
        {
            clsBatchInfo result = new clsBatchInfo();
            try
            {
                switch (rvMsg.Header)
                {
                    case "EQPJIP":
                    case "JIPINFOR":
                    {
                        result.TransID = rvMsg.GetValueByKey("TID");
                        result.BatchID = rvMsg.GetValueByKey("BATCH");
                        result.EQP = rvMsg.GetValueByKey("EQP");
                        result.PPID = rvMsg.GetValueByKey("PPID");
                        result.BatchSize = Convert.ToInt32(rvMsg.GetValueByKey("BATCHSIZE"));
                        result.Lots = new List<clsLotInfo>();
                        for (int i = 1; i <= result.BatchSize; i++)
                        {
                            clsLotInfo lot = ParseLotInfo(rvMsg, i);
                            result.Lots.Add(lot);
                        }
                        break;
                    }
                    case "BATCHUNLOADREQUEST":
                    case "QUERYUNLOADREQUESTR":
                	{
                        result.TransID = rvMsg.GetValueByKey("TID");
                        result.BatchID = rvMsg.GetValueByKey("BATCHID");
                        result.EQP = rvMsg.GetValueByKey("EQP");
                        string[] lotids = rvMsg.GetValueByKey("JOB").Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                        result.BatchSize = lotids.Length;
                        result.Lots = new List<clsLotInfo>();
                        for (int i = 1; i <= result.BatchSize; i++)
                        {
                            clsLotInfo lot = ParseLotInfo(rvMsg, i);
                            result.Lots.Add(lot);
                        }
                		break;
                	}
                    case "JOR":
                    {
                        result.TransID = rvMsg.GetValueByKey("TID");
                        result.BatchID = rvMsg.GetValueByKey("BATCH");
                        result.EQP = rvMsg.GetValueByKey("EQP");
                        result.BatchSize = Convert.ToInt32(rvMsg.GetValueByKey("BATCHSIZE"));
                        result.Lots = new List<clsLotInfo>();
                        for (int i = 1; i <= result.BatchSize; i++)
                        {
                            clsLotInfo lot = ParseLotInfo(rvMsg, i);
                            result.Lots.Add(lot);
                        }
                        break;
                    }
                    default :
                	{
                		break;
                	}
                }                
            }
            catch (System.Exception ex)
            {
                result = null;
            }
            return result;
        }

        public static clsLotInfo ParseLotInfo(clsRVMsg rvMsg, int Lot_Index = 1)
        {
            clsLotInfo result = null;
            try
            {
                switch (rvMsg.Header)
                {
                    case "GETLOTINFOFULLR":
                    {

                        break;
                    }
                    case "LOTINFOR":
                    {
                        string lotid = rvMsg.GetValueByKey("JOB", Lot_Index);
                        result = new clsLotInfo(lotid);
                        result.PPID = rvMsg.GetValueByKey("PPID");
                        result.LotType = rvMsg.GetValueByKey("LOTTYPE");
                        result.StepID = rvMsg.GetValueByKey("STEPID");
                        result.Capa = rvMsg.GetValueByKey("CAPA");
                        result.Pri = rvMsg.GetValueByKey("PRIORITY");
                        result.Qty = rvMsg.GetValueByKey("QTY");
                        result.EQP = rvMsg.GetValueByKey("EQP");
                        break;
                    }
                    case "EQPJIP":
                    case "JIPINFOR":
                    {
                        string lotid = rvMsg.GetValueByKey("JOB", Lot_Index);
                        result = new clsLotInfo(lotid);
                        result.TransID = rvMsg.GetValueByKey("TID");
                        result.Batch = rvMsg.GetValueByKey("BATCH");
                        result.BatchSize = rvMsg.GetValueByKey("BATCHSIZE");
                        result.Operator = rvMsg.GetValueByKey("OPERATOR");
                        result.PPID = rvMsg.GetValueByKey("PPID");
                        result.EQP = rvMsg.GetValueByKey("EQP");
                        result.EQP_Port = Lot_Index.ToString();
                        result.Capa = rvMsg.GetValueByKey("CAPA", Lot_Index);
                        result.CasID = rvMsg.GetValueByKey("CASID", Lot_Index);
                        result.CleanDate = rvMsg.GetValueByKey("CLN", Lot_Index);
                        result.Comments = rvMsg.GetValueByKey("CMT", Lot_Index);
                        result.DueDate = rvMsg.GetValueByKey("DUE", Lot_Index);
                        result.LotType = rvMsg.GetValueByKey("LOTTYPE", Lot_Index);
                        result.Mode = rvMsg.GetValueByKey("MODE", Lot_Index);
                        result.NLoc = rvMsg.GetValueByKey("NLOC", Lot_Index);
                        result.NStg = rvMsg.GetValueByKey("NSTG", Lot_Index);
                        result.Parameter = rvMsg.GetValueByKey("PARAMETER", Lot_Index);
                        result.Part = rvMsg.GetValueByKey("PART", Lot_Index);
                        result.Pri = rvMsg.GetValueByKey("PRI", Lot_Index);
                        result.Proc = rvMsg.GetValueByKey("PROC", Lot_Index);
                        result.Qty = rvMsg.GetValueByKey("QTY", Lot_Index);
                        result.Rcp = rvMsg.GetValueByKey("RCP", Lot_Index);
                        result.Reticle = rvMsg.GetValueByKey("RETICLE", Lot_Index);
                        result.StepID = rvMsg.GetValueByKey("STEPID", Lot_Index);
                        result.Stg = rvMsg.GetValueByKey("STG", Lot_Index);
                        result.Stus = rvMsg.GetValueByKey("STUS", Lot_Index);
                        result.Loc = string.Empty;
                        result.Recipe_Parameter = string.Empty;
                        result.RackID = string.Empty;
                        result.RackPosition = null;
                        break;
                    }
                    case "BATCHUNLOADREQUEST":
                    case "QUERYUNLOADREQUESTR":
                    {
                        string lotid = rvMsg.GetValueByKey("JOB", Lot_Index);
                        result = new clsLotInfo(lotid);
                        result.Batch = rvMsg.GetValueByKey("BATCHID");
                        result.EQP = rvMsg.GetValueByKey("EQP");
                        result.EQP_Port = rvMsg.GetValueByKey("SMIFID", Lot_Index).Substring(0, 1);
                        break;
                    }
                    case "JOR":
                    {
                        string lotid = rvMsg.GetValueByKey("JOB", Lot_Index);
                        result = new clsLotInfo(lotid);
                        string[] jobinfos = rvMsg.GetValueByKey("JOBINFO").Split("|".ToCharArray());
                        clsRVMsg msg = new clsRVMsg(jobinfos[Lot_Index - 1]);
                        if (msg != null)
                        {
                            result.Batch = rvMsg.GetValueByKey("BATCH");
                            result.EQP = rvMsg.GetValueByKey("EQP");
                            result.BatchSize = rvMsg.GetValueByKey("BATCHSIZE");
                            result.Rcp = rvMsg.GetValueByKey("RCP");
                            result.Capa = msg.GetValueByKey("CAPA");
                            result.Qty = msg.GetValueByKey("QTY");
                            result.Pri = msg.GetValueByKey("PRI");
                            result.Stg = msg.GetValueByKey("STG");
                            result.Part = msg.GetValueByKey("PART");
                            result.Stus = msg.GetValueByKey("STUS");
                            result.PPID = rvMsg.GetValueByKey("PPID");
                            result.NLoc = rvMsg.GetValueByKey("NLOC");
                            result.NStg = rvMsg.GetValueByKey("NSTG");
                            result.DueDate = rvMsg.GetValueByKey("DUE");
                            result.Mode = rvMsg.GetValueByKey("MODE");
                            result.CleanDate = rvMsg.GetValueByKey("CLN");
                        }                        
                        break;
                    }
                    default:
                    {
                        break;
                    }
                }
            }
            catch (System.Exception ex)
            {
                result = null;
            }
            return result;
        }

        public static clsToolInfo ParseToolInfo(clsRVMsg rvMsg, clsToolList ToolList = null)
        {
            clsToolInfo result = null;
            try
            {
                string eqp = rvMsg.GetValueByKey("EQP");
                if (ToolList == null)
                {
                    result = new clsToolInfo(eqp);
                } 
                else
                {
                    result = ToolList.FindTool(eqp);
                }                
                if (result != null)
                {
                    string value = rvMsg.GetValueByKey("EQPSTATUS");
                    result.ToolStatus = value;
                    value = rvMsg.GetValueByKey("EQPPORT");
                    string[] portids = value.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    result.MESPorts.Clear();
                    result.EAPPorts.Clear();
                    foreach (string portid in portids)
                    {
                        clsPortInfo MESPortObj = new clsPortInfo(portid);
                        result.MESPorts.Add(MESPortObj.PortID, MESPortObj);
                        clsPortInfo EAPPortObj = new clsPortInfo(portid);
                        result.EAPPorts.Add(EAPPortObj.PortID, EAPPortObj);
                    }
                    value = rvMsg.GetValueByKey("PORTINFOLIST");
                    string[] portstatuss = value.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    foreach (string portstatus in portstatuss)
                    {
                        string[] tmpStatus = portstatus.Split(":".ToCharArray());
                        string portid = tmpStatus[0];
                        string status = tmpStatus[1];
                        clsPortInfo port = null;
                        result.MESPorts.TryGetValue(portid, out port);
                        if (port != null)
                        {
                            port.Status = status;
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                result = null;
            }
            return result;
        }

        public static string Create_AGV_Command(clsAGVInfo agvinfo)
        {
            string result = string.Empty;
            try
            {
                string MissionID = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                string cmd = string.Empty;
                List<clsAGVCommand> agvcmds = agvinfo.AGV_Commands;
                Dictionary<int, clsLotInfo> LotList = new Dictionary<int, clsLotInfo>();

                foreach (clsAGVCommand agvcmd in agvcmds)
                {
                    switch (agvcmd.AGV_Cmd)
                    {
                        case clsAGVCommand.AGV_Cmd_Type.Pickup:
                            {
                                cmd += "P";
                                break;
                            }
                        case clsAGVCommand.AGV_Cmd_Type.Dropoff:
                            {
                                cmd += "D";
                                break;
                            }
                        case clsAGVCommand.AGV_Cmd_Type.Swap:
                            {
                                cmd += "S";
                                break;
                            }
                        default:
                            {
                                break;
                            }
                    }
                    foreach (int index in agvcmd.LotList.Keys)
                    {
                        clsLotInfo lot = null;
                        agvcmd.LotList.TryGetValue(index, out lot);
                        cmd += index.ToString();
                        try
                        {
                            LotList.Add(index, lot);
                        }
                        catch (System.Exception ex)
                        {
                        }
                    }
                }
                //mission.TID = GetTransID();

                cmd += " ";
                cmd += "TID=" + GetTransID() + " ";
                cmd += "MISSIONID=" + MissionID + " ";
                foreach (int key in LotList.Keys)
                {
                    clsLotInfo lot = null;
                    LotList.TryGetValue(key, out lot);
                    if (lot != null)
                    {
                        cmd += "SRC" + key.ToString() + "=" + lot.Src + " ";
                        cmd += "LOT" + key.ToString() + "=" + lot.LotID + " ";
                        cmd += "QTY" + key.ToString() + "=" + lot.Qty + " ";
                        cmd += $"DES{key.ToString()}={lot.Des} ";
                        cmd += $"SRC_TYPE{key.ToString()}={(lot.Src.Contains("ARERK") ? 0 : 1)} ";
                        cmd += $"DEST_TYPE{key.ToString()}={(lot.Des.Contains("ARERK") ? 0 : 1)} ";
                        lot.AGV = agvinfo.AGVID;
                        lot.Mission = MissionID;
                    }
                }
                result = cmd;
            }
            catch (System.Exception ex)
            {
                result = string.Empty;
            }
            return result;
        }

        public static void RemovedLotFromBatchList(List<clsBatchInfo> BatchList, string LotID)
        {
            try
            {
                clsLotInfo LotInfo = null;
                clsBatchInfo BatchInfo = FindBatchByLotID(BatchList, LotID, out LotInfo);
                if (BatchInfo != null)
                {
                    BatchInfo.Lots.Remove(LotInfo);
                    if (BatchInfo.Lots.Count == 0)
                    {
                        RemovedBatchFromBatchList(BatchList, BatchInfo);
                    }
                }
            }
            catch (System.Exception ex)
            {	
            }
        }

        public static void RemovedLotFromBatchList(List<clsBatchInfo> BatchList, string BatchID, string LotID)
        {
            try
            {
                clsLotInfo LotInfo = null;
                clsBatchInfo BatchInfo = FindBatchByLotID(BatchList, BatchID, LotID, out LotInfo);
                if (BatchInfo != null)
                {
                    BatchInfo.Lots.Remove(LotInfo);
                    if (BatchInfo.Lots.Count == 0)
                    {
                        RemovedBatchFromBatchList(BatchList, BatchInfo);
                    }
                }
            }
            catch (System.Exception ex)
            {
            }
        }

        public static void RemovedLotFromBatchListByEQPPort(List<clsBatchInfo> BatchList, string EQP_ID, string Port_ID, string Lot_ID)
        {
            try
            {
            	foreach (clsBatchInfo batch in BatchList)
            	{
            	    foreach (clsLotInfo lot in batch.Lots)
            	    {
            	        if ((lot.EQP == EQP_ID) && (lot.EQP_Port == Port_ID))
            	        {
            	        	if (lot.IsUnlocked)
            	        	{
                                if (string.IsNullOrEmpty(lot.AGV))
                                {
                                    if (lot.LotID != Lot_ID)
                                    {
                                        RemovedLotFromBatchList(BatchList, batch.BatchID, lot.LotID);
                                        break;
                                    }                                    
                                }                                
            	        	}
            	        }
            	    }
            	}
            }
            catch (System.Exception ex)
            {	
            }
        }

        public static void RemovedBatchFromBatchList(List<clsBatchInfo> BatchList, string BatchID, string AGVID = null)
        {
            try
            {
                if (AGVID == null)
                {
                    foreach (clsBatchInfo batch in BatchList)
                    {
                        if (batch.BatchID == BatchID)
                        {
                            BatchList.Remove(batch);
                            break;
                        }
                    }
                }
                else
                {
                    foreach (clsBatchInfo batch in BatchList)
                    {
                        if ((batch.BatchID == BatchID) && (batch.AGV == AGVID))
                        {
                            BatchList.Remove(batch);
                            break;
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
            }
        }

        public static void RemovedBatchFromBatchList(List<clsBatchInfo> BatchList, clsBatchInfo Batch)
        {
            try
            {
                BatchList.Remove(Batch);
            }
            catch (System.Exception ex)
            {
            }
        }

        public static void RemovedBatchByMissionID(List<clsBatchInfo> BatchList, string MissionID, string AGVID = null)
        {
            try
            {
                if (AGVID == null)
                {
                    List<string> BatchIds = new List<string>();
                    foreach (clsBatchInfo batch in BatchList)
                    {
                        foreach (clsLotInfo lot in batch.Lots)
                        {
                            if (lot.Mission == MissionID)
                            {
                                BatchIds.Add(batch.BatchID);
                                break;
                            }
                        }
                    }
                    foreach (string batchid in BatchIds)
                    {
                        RemovedBatchFromBatchList(BatchList, batchid);
                    }
                }
                else
                {
                    List<string> BatchIds = new List<string>();
                    foreach (clsBatchInfo batch in BatchList)
                    {
                        foreach (clsLotInfo lot in batch.Lots)
                        {
                            if ((lot.Mission == MissionID) && (lot.AGV == AGVID))
                            {
                                BatchIds.Add(batch.BatchID);
                                break;
                            }
                        }
                    }
                    foreach (string batchid in BatchIds)
                    {
                        RemovedBatchFromBatchList(BatchList, batchid, AGVID);
                    }
                }
            }
            catch (System.Exception ex)
            {
            }
        }

        public static clsBatchInfo Find_Batch_By_LotID_On_AGV(List<clsBatchInfo> BatchList, string LotID, bool Is_OnAGV, out clsLotInfo LotInfo)
        {
            clsBatchInfo result = null;
            LotInfo = null;
            try
            {
                foreach (clsBatchInfo batch in BatchList)
                {
                    if (Is_OnAGV)
                    {
                    	if (!string.IsNullOrEmpty(batch.AGV))
                    	{                    	
                            LotInfo = batch.FindLotByLotID(LotID);
                            if (LotInfo != null)
                            {
                                result = batch;
                                break;
                            }
                    	}
                    } 
                    else
                    {
                        if (string.IsNullOrEmpty(batch.AGV))
                        {
                            LotInfo = batch.FindLotByLotID(LotID);
                            if (LotInfo != null)
                            {
                                result = batch;
                                break;
                            }
                        }
                    }                    
                }
            }
            catch (System.Exception ex)
            {
                result = null;
                LotInfo = null;
            }
            return result;
        }

        public static List<clsBatchInfo> FindBatchByLotID(List<clsBatchInfo> BatchList, string LotID)
        {
            List<clsBatchInfo> result = new List<clsBatchInfo>();
            try
            {
                foreach (clsBatchInfo batch in BatchList)
                {
                    clsLotInfo LotInfo = batch.FindLotByLotID(LotID);
                    if (LotInfo != null)
                    {
                        result.Add(batch);
                    }
                }
            }
            catch (System.Exception ex)
            {
                result = null;
            }
            return result;
        }

        public static clsBatchInfo FindBatchByLotID(List<clsBatchInfo> BatchList, string LotID, out clsLotInfo LotInfo)
        {
            clsBatchInfo result = null;
            LotInfo = null;
            try
            {
                foreach (clsBatchInfo batch in BatchList)
                {
                    LotInfo = batch.FindLotByLotID(LotID);
                    if (LotInfo != null)
                    {
                        result = batch;
                        break;
                    }
                }
            }
            catch (System.Exception ex)
            {
                result = null;
                LotInfo = null;
            }
            return result;
        }

        public static clsBatchInfo FindBatchByLotID(List<clsBatchInfo> BatchList, string BatchID, string LotID, out clsLotInfo LotInfo)
        {
            clsBatchInfo result = null;
            LotInfo = null;
            try
            {
                List<clsBatchInfo> batchs = FindBatchByLotID(BatchList, LotID);
                foreach (clsBatchInfo batch in batchs)
                {
                    LotInfo = batch.FindLotByLotID(LotID);
                    if (LotInfo != null)
                    {
                        result = batch;
                        break;
                    }
                }
            }
            catch (System.Exception ex)
            {
                result = null;
                LotInfo = null;
            }
            return result;
        }

        public static clsBatchInfo FindBatchByBatchID(List<clsBatchInfo> BatchList, string BatchID)
        {
            clsBatchInfo result = null;
            try
            {
                foreach (clsBatchInfo batch in BatchList)
                {
                    if (batch.BatchID == BatchID)
                    {
                        result = batch;
                        break;
                    }
                }
            }
            catch (System.Exception ex)
            {
                result = null;
            }
            return result;
        }

        public static List<clsBatchInfo> FindBatchsByMissionID(List<clsBatchInfo> BatchList, string MissionID, string AGV_ID)
        {
            List<clsBatchInfo> result = new List<clsBatchInfo>();
            try
            {
                foreach (clsBatchInfo batch in BatchList)
                {
                    foreach(clsLotInfo lot in batch.Lots)
                    {
                        if (lot.Mission == MissionID)
                        {
                            if (lot.AGV == AGV_ID)
                            {
                                result.Add(batch);
                                break;
                            }                            
                        }
                    }                    
                }
            }
            catch (System.Exception ex)
            {
                result = new List<clsBatchInfo>();
            }
            return result;
        }

        public static void Add_Batch_To_BatchList(List<clsBatchInfo> BatchList, clsBatchInfo BatchInfo)
        {
            try
            {
                var tempObj = (clsBatchInfo)BatchInfo.Clone();
                clsBatchInfo ExistBatch = FindBatchByBatchID(BatchList, tempObj.BatchID);
                if (ExistBatch == null)
                {
                    BatchList.Add(tempObj);
                } 
                else
                {
                    ExistBatch = tempObj;
                }
            }
            catch (System.Exception ex)
            {
            }
        }

        public static bool Check_Tool_Status(clsToolInfo tool)
        {
            bool result = false;
            try
            {
                if (tool != null)
                {
                    string[] ToolStatus = { "1", "2", "8" };
                    if (Array.IndexOf(ToolStatus, tool.ToolStatus.ToUpper()) < 0)
                    {
                        result = false;
                        return result;
                    }
                }
                else
                {
                    result = false;
                    return result;
                }
                result = true;
            }
            catch (System.Exception ex)
            {
                result = false;
            }
            return result;
        }

    }
}
